package service.impl;

import common.consts.Consts;
import dao.*;
import domain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import service.OfferService;
import service.ServiceResponse;
import service.util.RowDataUtil;
import utils.Nulls;
import wrapper.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by aceyin on 15/7/3.
 */
@Service
public class OfferServiceImpl extends ServiceBase implements OfferService {
    @Autowired
    private OfferDao offerDao;
    @Autowired
    private RecruitmentDao recruitmentDao;
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private WorkLocationDao workLocationDao;
    @Autowired
    private ApplyConditionDao applyConditionDao;
    @Autowired
    private UserProfileDao profileDao;
    @Autowired
    private UserDataProfileDao dataProfileDao;
    @Autowired
    private UserLocationDao userLocationDao;
    @Autowired
    private CompanyDao companyDao;


    @Override
    public ServiceResponse viewOffer(long viewer, long id) {
        Offer offer = offerDao.get(id);
        if (offer == null) {
            return ServiceResponse.fail(Consts.i18nKey.INVALID_OFFER);
        }
        long applier = offer.getApplier();
        if (applier != viewer) {
            return ServiceResponse.fail(Consts.i18nKey.CANNOT_VIEW_OTHERS_OFFER);
        }

        UserLocation location = userLocationDao.get(viewer);

        DetailOfferWrapper wrapper = wrapOffer4Detail(offer, location.getLongitude(), location.getLatitude());

        return ServiceResponse.success().with("offer", wrapper);
    }

    /**
     * 封装 『查看offer详情』功能所需的数据
     *
     * @param offer
     * @return
     */
    private DetailOfferWrapper wrapOffer4Detail(Offer offer, Double lng, Double lat) {
        Nulls.fixWithDefault(lng, lat);

        Long recruitmentId = offer.getRecruitmentId();

        // wrap recruitment
        Map<String, Object> row = recruitmentDao.getWithDistance(recruitmentId, lng, lat);
        if (row == null) {
            return null;
        }

        DetailRecruitment4Worker recruitmentWrapper = new DetailRecruitment4Worker();
        Map<String, Object> map = RowDataUtil.toCamelCase(row);
        Recruitment recruitment = RowDataUtil.fill(map, Recruitment.class);
        WorkLocationWithDistance location = RowDataUtil.fill(map, WorkLocationWithDistance.class);
        ApplyCondition condition = RowDataUtil.fill(map, ApplyCondition.class);

        List<Workmate> workmates = getWorkmates(offer.getId());
        recruitmentWrapper.setRecruitment(recruitment);
        recruitmentWrapper.setWorkLocation(location);
        recruitmentWrapper.setApplyCondition(condition);
        recruitmentWrapper.setWorkmates(workmates);

        long employerId = offer.getEmployer();
        Employer employer = getEmployer(employerId);

        recruitmentWrapper.setEmployer(employer);

        DetailOfferWrapper wrapper = new DetailOfferWrapper();
        wrapper.setOffer(offer);
        wrapper.setRecruitment(recruitmentWrapper);
        return wrapper;
    }

    private Employer getEmployer(long employerId) {
        UserProfile employerProfile = profileDao.get(employerId);
        Company company = companyDao.findByOwner(employerId);

        Employer employer = new Employer();
        employer.setProvince(company.getProvince());
        employer.setName(employerProfile.getName());
        employer.setDistrict(company.getDistrict());
        employer.setCompanyName(company.getName());
        employer.setCity(company.getCity());
        employer.setCompanyIntro(company.getDescription());
        employer.setMobile(employerProfile.getPhone());
        return employer;
    }

    @Override
    public ServiceResponse listOfferByStatus(long user, String stat, int page, int rows) {
        List<SimpleOfferWrapper> wrappers = new ArrayList<>();

        List<Offer> offers = offerDao.findUserOffersByStatus(user, stat, page, rows);
        if (offers == null || offers.size() <= 0) {
            return ServiceResponse.success().with("offers", wrappers);
        }

        UserLocation location = userLocationDao.get(user);

        for (Offer offer : offers) {
            SimpleOfferWrapper wrapper = wrapOffer4List(offer, location.getLongitude(), location.getLatitude());
            wrappers.add(wrapper);
        }

        return ServiceResponse.success().with("offers", wrappers);
    }

    /**
     * 封装『查看我的Offer列表』所需的数据
     *
     * @param offer
     * @return
     */
    private SimpleOfferWrapper wrapOffer4List(Offer offer, Double lng, Double lat) {
        lng = lng == null ? 0d : lng;
        lat = lat == null ? 0d : lat;

        Long recruitmentId = offer.getRecruitmentId();

        Map<String, Object> map = recruitmentDao.getWithDistance(recruitmentId, lng, lat);
        Map<String, Object> camelCase = RowDataUtil.toCamelCase(map);
        Recruitment recruitment = RowDataUtil.fill(camelCase, Recruitment.class);
        WorkLocationWithDistance location = RowDataUtil.fill(camelCase, WorkLocationWithDistance.class);
        ApplyCondition condition = RowDataUtil.fill(camelCase, ApplyCondition.class);

        SimpleRecruitment4Worker rec = new SimpleRecruitment4Worker();
        rec.setRecruitment(recruitment);
        rec.setApplyCondition(condition);
        rec.setWorkLocation(location);

        SimpleOfferWrapper wrapper = new SimpleOfferWrapper();
        wrapper.setOffer(offer);
        wrapper.setRecruitment(rec);
        return wrapper;
    }

    private List<Workmate> getWorkmates(long offerId) {
        List<Long> ids = offerDao.getApplierIds(offerId);
        List<Workmate> workmates = new ArrayList<>();
        if (!ids.isEmpty()) {
            for (Long id : ids) {
                Workmate workmate = new Workmate();

                Account account = accountDao.get(id);
                workmate.setNick(account.getNick());
                workmate.setId(id);
                workmate.setAvatar(account.getAvatar());

                UserProfile profile = profileDao.get(id);
                workmate.setName(profile.getName());
                workmate.setGender(profile.getGender());

                UserDataProfile dataProfile = dataProfileDao.get(id);
                workmate.setReceivedEggs(dataProfile.getReceivedEggs());
                workmate.setReceivedEggs(dataProfile.getReceivedEggs());
                workmate.setWorkDoneTimes(dataProfile.getWorkDoneTimes());

                workmates.add(workmate);
            }
        }
        return workmates;
    }
}
